//
// Created by hkkzzxz on 24-9-2.
//

#include <iomanip>
#include "EmployeeController.h"
#include "EmployeeService.h"

void EmployeeController::employeeRegister(std::string &uuid, http::request<http::dynamic_body> &httpRequest,
                                          http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    Json::Value srcRoot;

    //尝试解析字符串
    if (parseRequestBody(httpRequest, srcRoot)) {
        auto id = srcRoot["id"].asString();
        auto name = srcRoot["name"].asString();
        auto phoneNumber = srcRoot["phone_number"].asString();
        auto password = srcRoot["password"].asString();

        std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
        bool result = employeeService->employRegister(id, name, phoneNumber, password);

        if (result) {
            httpResponse.result(http::status::ok);
            root["code"] = 0;
            root["message"] = "Successfully register";
        } else {
            httpResponse.result(http::status::bad_request);
            root["code"] = 1002;
            root["message"] = "Failed to register";
        }
    } else {
        httpResponse.result(http::status::bad_request);
        root["code"] = 1001;
        root["message"] = "Failed to parse JSON data!";
    }
    root["data"] = srcRoot;

    // 设置响应内容
    setHttpResponse(httpResponse, root);
}

void EmployeeController::forgetPassword(std::string &data, http::request<http::dynamic_body> &httpRequest,
                                        http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    Json::Value srcRoot;

    //尝试解析字符串
    if (parseRequestBody(httpRequest, srcRoot)) {
        auto id = srcRoot["id"].asString();
        auto name = srcRoot["name"].asString();
        auto phoneNumber = srcRoot["phone_number"].asString();
        auto password = srcRoot["password"].asString();

        std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
        if (employeeService->forgetPassword(id, name, phoneNumber, password)) {
            httpResponse.result(http::status::ok);
            root["code"] = 0;
            root["message"] = "Successful reset password";
        } else {
            httpResponse.result(http::status::bad_request);
            root["code"] = 1002;
            root["message"] = "Failed reset password";
        }
    } else {
        httpResponse.result(http::status::bad_request);
        root["code"] = 1001;
        root["message"] = "Failed to parse JSON data!";
    }
    root["data"] = srcRoot;
    setHttpResponse(httpResponse, root);
}

void EmployeeController::modifyPhoneNumber(std::string &id, http::request<http::dynamic_body> &httpRequest,
                                           http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    Json::Value srcRoot;

    //尝试解析字符串
    if (parseRequestBody(httpRequest, srcRoot)) {
        auto phoneNumber = srcRoot["phone_number"].asString();
        auto newPhoneNumber = srcRoot["new_phone_number"].asString();

        std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
        if (employeeService->modifyPhoneNumber(id, phoneNumber, newPhoneNumber)) {
            httpResponse.result(http::status::ok);
            root["code"] = 0;
            root["message"] = "Successful modify phone number";
        } else {
            httpResponse.result(http::status::bad_request);
            root["code"] = 1002;
            root["message"] = "Failed modify phone number";
        }
    } else {
        httpResponse.result(http::status::bad_request);
        root["code"] = 1001;
        root["message"] = "Failed to parse JSON data!";
    }
    root["data"] = srcRoot;
    setHttpResponse(httpResponse, root);
}

void EmployeeController::modifyPassword(std::string &id, http::request<http::dynamic_body> &httpRequest,
                                        http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    Json::Value srcRoot;

    //尝试解析字符串
    if (parseRequestBody(httpRequest, srcRoot)) {
        auto password = srcRoot["password"].asString();
        auto newPassword = srcRoot["new_password"].asString();

        std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
        if (employeeService->modifyPassword(id, password, newPassword)) {
            httpResponse.result(http::status::ok);
            root["code"] = 0;
            root["message"] = "Successful modify password";
        } else {
            httpResponse.result(http::status::bad_request);
            root["code"] = 1002;
            root["message"] = "Failed modify password";
        }
    } else {
        httpResponse.result(http::status::bad_request);
        root["code"] = 1001;
        root["message"] = "Failed to parse JSON data!";
    }
    root["data"] = srcRoot;
    setHttpResponse(httpResponse, root);
}

void EmployeeController::generateFingerprintID(std::string &data, http::request<http::dynamic_body> &httpRequest,
                                               http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    Json::Value srcRoot;

    root["data"] = "";
    //尝试解析字符串
    if (parseRequestBody(httpRequest, srcRoot)) {
        auto id = srcRoot["id"].asString();

        std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
        auto result = employeeService->generateFingerprintID(id);
        if (!result.empty()) {
            httpResponse.result(http::status::ok);
            root["code"] = 0;
            root["data"] = result;
            root["message"] = "Successful generate fingerprint ID";
        } else {
            httpResponse.result(http::status::bad_request);
            root["code"] = 1002;
            root["message"] = "Failed generate fingerprint ID";
        }
    } else {
        httpResponse.result(http::status::bad_request);
        root["code"] = 1001;
        root["message"] = "Failed to parse JSON data!";
    }
    setHttpResponse(httpResponse, root);
}

void EmployeeController::fingerprintAttendance(std::string &data, http::request<http::dynamic_body> &httpRequest,
                                               http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    Json::Value srcRoot;

    root["data"] = "";
    //尝试解析字符串
    if (parseRequestBody(httpRequest, srcRoot)) {
        auto fingerprintID = srcRoot["fingerprintID"].asString();

        std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
        auto result = employeeService->fingerprintAttendance(fingerprintID);
        if (!result.empty()) {
            httpResponse.result(http::status::ok);
            root["code"] = 0;
            root["data"] = result;
            root["message"] = "Successful attendance";
        } else {
            httpResponse.result(http::status::bad_request);
            root["code"] = 1002;
            root["message"] = "Failed attendance";
        }
    } else {
        httpResponse.result(http::status::bad_request);
        root["code"] = 1001;
        root["message"] = "Failed to parse JSON data!";
    }
    setHttpResponse(httpResponse, root);
}

void EmployeeController::uploadAttendancePhoto(std::string &id, http::request<http::dynamic_body> &httpRequest,
                                               http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    std::string photo;

    try {
        // 从内容类型解析边界
        const auto &content_type = httpRequest[http::field::content_type];
        const auto boundary_pos = content_type.find("boundary=");
        if (boundary_pos == std::string::npos || content_type.find("multipart/form-data") == std::string::npos) {
            throw std::runtime_error("Boundary not found");
        }
        const std::string boundary = content_type.substr(boundary_pos + 9);

        // 将请求正文读入缓冲区
        beast::multi_buffer buffer;
        buffer.commit(boost::asio::buffer_copy(buffer.prepare(beast::buffer_bytes(httpRequest.body().data())),
                                               httpRequest.body().data()));
        std::string data;
        data.resize(boost::asio::buffer_size(httpRequest.body().data()));
        boost::asio::buffer_copy(boost::asio::buffer(data), httpRequest.body().data());
        const std::string delimiter = "--" + boundary;

        // 提取图像部分
        size_t pos = 0;
        while ((pos = data.find(delimiter, pos)) != std::string::npos) {
            const size_t end = data.find(delimiter, pos + delimiter.size());
            if (end == std::string::npos) break;

            const std::string part = data.substr(pos + delimiter.size(), end - pos - delimiter.size());
            pos = end;

            if (part.find("name=\"image\"") != std::string::npos) {
                const size_t file_start = part.find("\r\n\r\n");
                if (file_start != std::string::npos) {
                    const size_t content_start = file_start + 4; // skip the \r\n\r\n
                    const size_t file_end = part.find_last_not_of("\r\n") + 1;
                    photo = part.substr(content_start, file_end - content_start);
                    break;
                }
            }
        }

        if (photo.empty()) {
            throw std::runtime_error("Image part not found or empty");
        }
        std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
        if (employeeService->uploadAttendancePhoto(id, photo)) {
            httpResponse.result(http::status::ok);
            root["code"] = 0;
            root["message"] = "Successful upload attendance photo";
        } else {
            throw std::runtime_error("Failed to upload attendance photo");
        }
    } catch (const std::exception &e) {
        httpResponse.result(http::status::bad_request);
        root["code"] = 1001;
        root["message"] = e.what();
    }

    root["data"] = "";
    setHttpResponse(httpResponse, root);
}

void EmployeeController::facialAttendance(std::string &data, http::request<http::dynamic_body> &httpRequest,
                                          http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    std::string photo;
    root["data"] = "";

    try {
        // 从内容类型解析边界
        const auto &content_type = httpRequest[http::field::content_type];
        const auto boundary_pos = content_type.find("boundary=");
        if (boundary_pos == std::string::npos || content_type.find("multipart/form-data") == std::string::npos) {
            throw std::runtime_error("Boundary not found");
        }
        const std::string boundary = content_type.substr(boundary_pos + 9);

        // 将请求正文读入缓冲区
        beast::multi_buffer buffer;
        buffer.commit(boost::asio::buffer_copy(buffer.prepare(beast::buffer_bytes(httpRequest.body().data())),
                                               httpRequest.body().data()));
        std::string reqData;
        reqData.resize(boost::asio::buffer_size(httpRequest.body().data()));
        boost::asio::buffer_copy(boost::asio::buffer(reqData), httpRequest.body().data());
        const std::string delimiter = "--" + boundary;

        // 提取图像部分
        size_t pos = 0;
        while ((pos = reqData.find(delimiter, pos)) != std::string::npos) {
            const size_t end = reqData.find(delimiter, pos + delimiter.size());
            if (end == std::string::npos) break;

            const std::string part = reqData.substr(pos + delimiter.size(), end - pos - delimiter.size());
            pos = end;

            if (part.find("name=\"image\"") != std::string::npos) {
                const size_t file_start = part.find("\r\n\r\n");
                if (file_start != std::string::npos) {
                    const size_t content_start = file_start + 4; // skip the \r\n\r\n
                    const size_t file_end = part.find_last_not_of("\r\n") + 1;
                    photo = part.substr(content_start, file_end - content_start);
                    break;
                }
            }
        }

        if (photo.empty()) {
            throw std::runtime_error("Image part not found or empty");
        }
        std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
        auto result = employeeService->facialAttendance(photo);
        if (!result.empty()) {
            httpResponse.result(http::status::ok);
            root["code"] = 0;
            root["data"] = result;
            root["message"] = "Successful attendance";
        } else {
            throw std::runtime_error("Failed attendance");
        }
    } catch (const std::exception &e) {
        httpResponse.result(http::status::bad_request);
        root["code"] = 1001;
        root["message"] = e.what();
    }

    setHttpResponse(httpResponse, root);
}

void EmployeeController::checkTodayAttendance(std::string &id, http::request<http::dynamic_body> &httpRequest,
                                              http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
    auto result = employeeService->checkTodayAttendance(id);
    if (result.empty()) {
        httpResponse.result(http::status::ok);
        root["code"] = 1;
        root["data"] = "";
        root["message"] = "today's attendance not found";
    } else {
        httpResponse.result(http::status::ok);
        root["code"] = 0;
        root["data"] = result;
        root["message"] = "check today attendance successful";
    }
    setHttpResponse(httpResponse, root);
}

void EmployeeController::checkAttendance(std::string &id, http::request<http::dynamic_body> &httpRequest,
                                         http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
    auto result = employeeService->checkAttendance(id);
    if (result.empty()) {
        httpResponse.result(http::status::ok);
        root["code"] = 1;
        root["data"] = "";
        root["message"] = "check attendance not found";
    } else {
        httpResponse.result(http::status::ok);
        root["code"] = 0;
        root["data"] = result;
        root["message"] = "check attendance successful";
    }
    setHttpResponse(httpResponse, root);
}

void EmployeeController::getName(std::string &data, http::request<http::dynamic_body> &httpRequest,
                                 http::response<http::dynamic_body> &httpResponse) {
    Json::Value root;
    Json::Value srcRoot;
    root["data"] = "";

    //尝试解析字符串
    if (parseRequestBody(httpRequest, srcRoot)) {
        auto id = srcRoot["id"].asString();

        std::unique_ptr<IEmployeeService> employeeService = std::make_unique<EmployeeService>();
        auto result = employeeService->getName(id);
        if (!result.empty()) {
            httpResponse.result(http::status::ok);
            root["code"] = 0;
            root["data"] = result;
            root["message"] = "Successful get employee's name";
        } else {
            httpResponse.result(http::status::bad_request);
            root["code"] = 1002;
            root["message"] = "Failed get employee's name";
        }
    } else {
        httpResponse.result(http::status::bad_request);
        root["code"] = 1001;
        root["message"] = "Failed to parse JSON data!";
    }

    setHttpResponse(httpResponse, root);
}

void EmployeeController::getTime(std::string &data, http::request<http::dynamic_body> &httpRequest,
                                 http::response<http::dynamic_body> &httpResponse) {
    httpResponse.result(http::status::ok);
    Json::Value root;
    root["code"] = 0;

    // 获取当前系统时间
    auto now = std::chrono::system_clock::now();
    auto in_time_t = std::chrono::system_clock::to_time_t(now);
    std::tm bt = *std::localtime(&in_time_t);
    std::ostringstream oss;
    oss << std::put_time(&bt, "%Y-%m-%d %H:%M:%S");
    root["data"] = oss.str();
    root["message"] = "Successful get time";

    setHttpResponse(httpResponse, root);
}
